from DrissionPage import Chromium
from DrissionPage import SessionPage
from DrissionPage.common import Settings
from datetime import datetime
from dateutil.relativedelta import relativedelta
import time
import re
import traceback

Settings.set_language('zh_cn')  # 设置为中文
file_path = ""
# 检索关键词
search_keywords = "鸿蒙Next"
verify_pattern = r'^(?=.*鸿蒙)(?=.*next)(?=.*(?:动画|动效)).+$'
file_path = "D:\workspace\crawler\data\哔哩哔哩.txt"

def ele_scroll_to_see(ele):
    ele.wait.has_rect()
    ele.scroll.to_see()

def process_video_card(video_card):
    new_tab = None
    try:
        # ele_scroll_to_see(video_card) # 不点击卡片，不需要滑动到可见区域
        texts = video_card.ele('@class=bili-video-card__info--right').texts()
        card_desc = "".join(texts)
        if not re.search(verify_pattern, card_desc, re.IGNORECASE):
            print(f'描述：{card_desc}\n')
            print('不包含检索关键词\n')
            return
        link_ele = video_card.ele('@class=bili-video-card__info--right').ele('@tag()=a')
        link_url = link_ele.attr('href')
        with open(file_path, 'a', encoding='utf-8') as f:
            f.write("描述：\n")
            f.write(card_desc + "\n")
            f.write("网址：\n")
            f.write(link_url + "\n")
            f.write('\n')
    except Exception:
        traceback.print_exc()
    finally:
        if new_tab:
            new_tab.close()

def process_card(card):
    card_title = card['title']
    card_desc = card['description']
    arcurl = card['arcurl']
    card_full_desc = card['title'] + card['description']
    if not re.search(verify_pattern, card_full_desc, re.IGNORECASE):
        print(f'标题：{card_title}\n')
        print(f'描述：{card_desc}\n')
        print('不包含检索关键词\n')
    else:
        with open(file_path, 'a', encoding='utf-8') as f:
            f.write(f'标题：\n{card_title}\n')
            f.write(f'描述：\n{card_desc}\n')
            f.write(f'网址：\n{arcurl}\n')
            f.write('\n')

def click_next_page(main_tab):
    try_count = 5
    while try_count >= 0:
        try:
            main_tab.wait.ele_displayed('@tag()=html').scroll.to_bottom()
            # 点击下一页
            next_btn = main_tab.wait.ele_displayed('@@class=vui_button vui_pagenation--btn vui_pagenation--btn-side@@text()=下一页')
            if not next_btn:
                print('没有下一页了\n')
                return False
            next_btn.click()
            break
        except Exception:
            print(f'点击下一页异常，等待一秒后重新尝试，剩余尝试次数：{try_count}\n')
            time.sleep(1)
            try_count = try_count - 1
    return True

def process_first_page(main_tab):
    try:
        video_card_list_ele = main_tab.wait.ele_displayed('@class=video-list row')
        video_card_list = video_card_list_ele.children()
        print("第一页卡片数量：" +str(len(video_card_list)))
        if not video_card_list:
            return
        card_num = 1
        for video_card in video_card_list:
            print(f'====================>>处理第{card_num}张卡')
            card_num = card_num + 1
            process_video_card(video_card)
    except Exception:
        traceback.print_exc()
    finally:
        click_next_page(main_tab)

# 启动或接管浏览器，并创建标签页对象
main_tab = Chromium().latest_tab
# 这之后出现的弹窗都会自动确认
main_tab.browser.set.auto_handle_alert()
# 跳转到哔哩哔哩
main_tab.get('https://www.bilibili.com/')
# 等待网页加载完成
main_tab.wait.load_start()

# 搜索关键词
main_tab.wait.ele_displayed('@class=nav-search-input').input(search_keywords, clear = True)
main_tab = main_tab.wait.ele_displayed('@class=nav-search-btn').click.for_new_tab()
# 等待网页加载完成
main_tab.wait.load_start()
main_tab.listen.start('https://api.bilibili.com/x/web-interface/wbi/search/type')

process_first_page(main_tab)
# 循环点击下一页
while True:
    try:
        body = main_tab.listen.wait(timeout=10).response.body # 等待并获取一个数据包
        if body['code'] != 0 or not body['data'] or not body['data']['result']:
            print('没有想要的数据了\n')
            break
        card_list = body['data']['result']
        for card in card_list:
            process_card(card)
        # 等待网页加载完成
        main_tab.wait.load_start()
    except Exception:
        traceback.print_exc()
    finally:            
        if not click_next_page(main_tab):
            break
